#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "port_manager.h"
// #include "kh_device_info.h"
#include "softbus_bus_center.h"
#include "transmission.h"

#define MAX_PORTS 13
#define DI_PORTS 6
#define DO_PORTS 6
#define UART_PORT 13

const char *deviceNetworkId = "some_network_id";

// 存储端口的上次和当前状态
int lastPortState[MAX_PORTS] = {0};
int currentPortState[MAX_PORTS] = {0};

// 初始化所有端口
void InitPorts(void) {
    DigiInit();
    for (int i = 1; i <= DI_PORTS; ++i) {
        IoTGpioInit(i);
        IoTGpioSetDir(i, IOT_GPIO_DIR_IN);
    }
    for (int i = 7; i <= DO_PORTS + 6; ++i) {
        IoTGpioInit(i);
        IoTGpioSetDir(i, IOT_GPIO_DIR_OUT);
    }
    IotUartAttribute uart_attr = {
        .baudRate = 115200,
        .dataBits = IOT_UART_DATA_BIT_8,
        .stopBits = IOT_UART_STOP_BIT_1,
        .parity = IOT_UART_PARITY_NONE,
    };
    IoTUartInit(UART_PORT, &uart_attr);
}

// 监听端口变化
void MonitorPorts(void) {
    for (int port = 1; port <= DI_PORTS; ++port) {
        uint8_t val;
        getDigiInput(port, &val);
        if (currentPortState[port] != val) {
            ReportPortChange(deviceNetworkId, port, val);
            currentPortState[port] = val;
        }
    }
}

// 端口变化上报函数
void ReportPortChange(const char *onlineNetworkId, int port, int newState) {
    printf("Port %d changed from %d to %d\n", port, lastPortState[port], newState);
    lastPortState[port] = newState; // 更新最后状态
    // 这里可以添加上报逻辑，例如发送到L2控制器
        lastPortState[port] = newState; // 更新最后状态
    // 构造响应数据并发送
    SendPortMsgInfo portInfo = {
        .port = port,
        .type = READ,
        .data = {/* JSON stringifying the state change */ }
    };
    BirefSendBytes(onlineNetworkId, portInfo, strlen(&portInfo));
}

// 解析L2下发的数据并控制端口
void ControlPort(const SendPortMsgInfo *portInfo) {
    switch (portInfo->type) {
        case READ:
            // 读取端口状态
            if (portInfo->port >= 1 && portInfo->port <= MAX_PORTS) {
                uint8_t val = 0;
                if (portInfo->port <= DI_PORTS) {
                    getDigiInput(portInfo->port, &val);
                } else if (portInfo->port == UART_PORT) {
                    // 读取UART端口状态
                }
                // 上报读取的状态
                printf("Read from port %d: %d\n", portInfo->port, val);
            }
            break;
        case WRITE:
            // 设置端口状态
            if (portInfo->port >= 7 && portInfo->port <= DO_PORTS + 6) {
                IotGpioValue value = IOT_GPIO_VALUE0;
                if (strcmp(portInfo->data, "1") == 0) {
                    value = IOT_GPIO_VALUE1;
                }
                IoTGpioSetOutputVal(portInfo->port, value);
            }
            break;
        case SUBSCRIBE:
            // 订阅端口变化
            break;
        case REGISTER_PORT2L2: // buxuyao
            // 注册端口到L2
            break;
        case RELEASE_AND_UNREGISTER:
            // 释放并取消注册端口
            break;
        case UPDATE_NODES_INFO:
            // 更新节点信息
            break;
        default:
            break;
    }
}

// UART控制端口
void UartControlPort(const SendPortMsgInfo *portInfo) {
    if (portInfo->port == UART_PORT) {
        if (portInfo->type == WRITE) {
            // 发送数据到UART
            IoTUartWrite(UART_PORT, (unsigned char *)portInfo->data, strlen(portInfo->data));
        } else if (portInfo->type == READ) {
            unsigned char uart_buff[1024] = {0};
            // 从UART读取数据
            IoTUartRead(UART_PORT, uart_buff, sizeof(uart_buff));
            printf("Read from UART: %s\n", uart_buff);
        }
    }
}

// 设置DO口开关信号
void SetDOSignal(int port, int value) {
    if (port >= 1 && port <= DO_PORTS) {
        IotGpioValue gpioValue = value ? IOT_GPIO_VALUE1 : IOT_GPIO_VALUE0;
        IoTGpioSetOutputVal(port + 6, gpioValue);
    }
}

// 设置DO口脉冲信号
void SetDOPulse(int port, int value, unsigned int duration) {
    if (port >= 1 && port <= DO_PORTS) {
        IotGpioValue gpioValue = value ? IOT_GPIO_VALUE1 : IOT_GPIO_VALUE0;
        IoTGpioSetOutputVal(port + 6, gpioValue); // 设置为高电平
        osDelay(duration * 1000); // 等待指定的脉冲宽度时间（毫秒）
        IoTGpioSetOutputVal(port + 6, !gpioValue); // 恢复为低电平
    }
}


int SendRegistrationToL2(const char *onlineNetworkId) {
    printf("******start SendRegistrationToL2*******\n");
    // 初始化结构体变量
    SendPortMsgInfo msgInfo;
    memset(&msgInfo, 0, sizeof(SendPortMsgInfo));
    strcpy(msgInfo.SN, "000000000000000002"); // 写死 SN  
    // strcpy(msgInfo.SN, getDeviceSN()); // 可以获取SN

    printf("******start GetLocalNodeDeviceInfo*******\n");
    // 获取本地的 networkId
    NodeBasicInfo localInfo;
    int ret = GetLocalNodeDeviceInfo(PKG_NAME, &localInfo);
    if (ret != 0) {
        printf("GetLocalNodeDeviceInfo fail, ret = %d.\n", ret);
        return -1;
    }
    strcpy(msgInfo.networkId, localInfo.networkId); 
    msgInfo.type = 3;

    //strcpy(msgInfo->networkId, GetNetworkId()); 
    //这个不对，用调用GetLocalNodeDeviceInfo(PKG_NAME, &info) 获取本地的networkId (info->networkId)；当然可以修改GetNetworkId()

    // 使用BirefSendBytes发送msgInfo结构体,将msgInfo的地址转换为const char*类型
    printf("******start BirefSendBytes*******\n");
    BirefCreateSessionServer();
    ret = BirefSendBytes(onlineNetworkId, (const char*)&msgInfo, sizeof(msgInfo));
    if (ret != 0) {
        printf("Failed to send registration message\n");
        return -1;
    }
    // OnBytesReceived();
    return 0;
}

int main() {
    // 初始化端口
    InitPorts();

    // 循环监听端口变化
    while (1) {
        MonitorPorts();
        osDelay(1000); // 1000ms
    }

    return 0;
}